package v1

import (
	"net/http"
	"strconv"

	"zhihu-api/models"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 创建答案请求
type CreateAnswerRequest struct {
	Content string `json:"content" binding:"required"`
}

// 创建答案
func CreateAnswer(c *gin.Context) {
	questionID := c.Param("id")
	userID := c.MustGet("userID").(uint)

	var req CreateAnswerRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 检查问题是否存在
	var question models.Question
	if err := models.DB.First(&question, questionID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	// 创建答案
	answer := models.Answer{
		Content:    req.Content,
		AnswererID: userID,
		QuestionID: question.ID,
	}

	tx := models.DB.Begin()

	if err := tx.Create(&answer).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建答案失败"})
		return
	}

	// 更新问题回答数
	if err := tx.Model(&question).Update("answer_count", gorm.Expr("answer_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新问题回答数失败"})
		return
	}

	tx.Commit()

	// 返回创建的答案(包含用户信息)
	if err := models.DB.Preload("Answerer").First(&answer, answer.ID).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案详情失败"})
		return
	}

	c.JSON(http.StatusCreated, answer)
}

// 获取问题的答案列表
func ListQuestionAnswers(c *gin.Context) {
	questionID := c.Param("id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	// 检查问题是否存在
	var question models.Question
	if err := models.DB.First(&question, questionID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	var answers []models.Answer
	if err := models.DB.Where("question_id = ?", questionID).
		Preload("Answerer").
		Order("vote_count DESC, created_at DESC").
		Limit(limit).Offset(offset).
		Find(&answers).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案列表失败"})
		return
	}

	c.JSON(http.StatusOK, answers)
}

// 获取答案详情
func GetAnswer(c *gin.Context) {
	answerID := c.Param("answerId")

	var answer models.Answer
	if err := models.DB.Preload("Answerer").Preload("Question").First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	c.JSON(http.StatusOK, answer)
}

// 更新答案请求
type UpdateAnswerRequest struct {
	Content string `json:"content" binding:"required"`
}

// 更新答案
func UpdateAnswer(c *gin.Context) {
	answerID := c.Param("answerId")
	userID := c.MustGet("userID").(uint)

	var req UpdateAnswerRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 检查答案是否存在
	var answer models.Answer
	if err := models.DB.First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	// 检查权限
	if answer.AnswererID != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有权限更新此答案"})
		return
	}

	// 更新答案
	if err := models.DB.Model(&answer).Update("content", req.Content).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新答案失败"})
		return
	}

	// 返回更新后的答案
	if err := models.DB.Preload("Answerer").First(&answer, answerID).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取更新后的答案失败"})
		return
	}

	c.JSON(http.StatusOK, answer)
}

// 删除答案
func DeleteAnswer(c *gin.Context) {
	answerID := c.Param("answerId")
	userID := c.MustGet("userID").(uint)

	// 检查答案是否存在
	var answer models.Answer
	if err := models.DB.First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	// 检查权限
	if answer.AnswererID != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有权限删除此答案"})
		return
	}

	tx := models.DB.Begin()

	// 删除答案
	if err := tx.Delete(&answer).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除答案失败"})
		return
	}

	// 更新问题回答数
	if err := tx.Model(&models.Question{}).Where("id = ?", answer.QuestionID).
		Update("answer_count", gorm.Expr("answer_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新问题回答数失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "答案删除成功"})
}

// 点赞答案
func LikeAnswer(c *gin.Context) {
	answerID := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(answerID, 10, 32)

	// 检查答案是否存在
	var answer models.Answer
	if err := models.DB.First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	// 检查是否已点赞
	var count int64
	models.DB.Model(&models.UserLikingAnswer{}).Where("user_id = ? AND answer_id = ?", userID, idUint).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "已经点赞该答案"})
		return
	}

	// 创建点赞关系
	liking := models.UserLikingAnswer{
		UserID:   userID,
		AnswerID: uint(idUint),
	}

	tx := models.DB.Begin()
	if err := tx.Create(&liking).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "点赞答案失败"})
		return
	}

	// 更新答案的点赞数量
	if err := tx.Model(&models.Answer{}).Where("id = ?", idUint).Update("vote_count", gorm.Expr("vote_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新答案点赞数量失败"})
		return
	}

	// 更新回答者获赞数
	if err := tx.Model(&models.User{}).Where("id = ?", answer.AnswererID).Update("liked_count", gorm.Expr("liked_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新用户获赞数失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "点赞答案成功"})
}

// 取消点赞答案
func UnlikeAnswer(c *gin.Context) {
	answerID := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(answerID, 10, 32)

	// 检查答案是否存在
	var answer models.Answer
	if err := models.DB.First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	// 检查是否已点赞
	var count int64
	models.DB.Model(&models.UserLikingAnswer{}).Where("user_id = ? AND answer_id = ?", userID, idUint).Count(&count)
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未点赞该答案"})
		return
	}

	tx := models.DB.Begin()
	// 删除点赞关系
	if err := tx.Where("user_id = ? AND answer_id = ?", userID, idUint).Delete(&models.UserLikingAnswer{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "取消点赞答案失败"})
		return
	}

	// 更新答案的点赞数量
	if err := tx.Model(&models.Answer{}).Where("id = ?", idUint).Update("vote_count", gorm.Expr("vote_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新答案点赞数量失败"})
		return
	}

	// 更新回答者获赞数
	if err := tx.Model(&models.User{}).Where("id = ?", answer.AnswererID).Update("liked_count", gorm.Expr("liked_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新用户获赞数失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "取消点赞答案成功"})
}

// 收藏答案
func CollectAnswer(c *gin.Context) {
	answerID := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(answerID, 10, 32)

	// 检查答案是否存在
	var answer models.Answer
	if err := models.DB.First(&answer, answerID).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "答案不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取答案失败"})
		return
	}

	// 检查是否已收藏
	var count int64
	models.DB.Model(&models.UserCollectingAnswer{}).Where("user_id = ? AND answer_id = ?", userID, idUint).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "已经收藏该答案"})
		return
	}

	// 创建收藏关系
	collecting := models.UserCollectingAnswer{
		UserID:   userID,
		AnswerID: uint(idUint),
	}

	if err := models.DB.Create(&collecting).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "收藏答案失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "收藏答案成功"})
}

// 取消收藏答案
func UncollectAnswer(c *gin.Context) {
	answerID := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(answerID, 10, 32)

	// 检查是否已收藏
	var count int64
	models.DB.Model(&models.UserCollectingAnswer{}).Where("user_id = ? AND answer_id = ?", userID, idUint).Count(&count)
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未收藏该答案"})
		return
	}

	// 删除收藏关系
	if err := models.DB.Where("user_id = ? AND answer_id = ?", userID, idUint).Delete(&models.UserCollectingAnswer{}).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "取消收藏答案失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "取消收藏答案成功"})
}

// 获取用户收藏的答案列表
func GetUserCollections(c *gin.Context) {
	id := c.Param("id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	var answers []models.Answer
	if err := models.DB.Joins("JOIN user_collecting_answers ON answers.id = user_collecting_answers.answer_id").
		Where("user_collecting_answers.user_id = ?", id).
		Preload("Answerer").Preload("Question").
		Order("user_collecting_answers.created_at DESC").
		Limit(limit).Offset(offset).Find(&answers).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取收藏列表失败"})
		return
	}

	c.JSON(http.StatusOK, answers)
}
